Skip layout shift tracking for more invisible elements Besides the current conditions, e.g. visibility:hidden, opacity:0 (which is checked in PaintInvalidator instead of LayoutShiftTracker) etc., also ignore the following invisible elements: - For texts: - if the font is not renderable - if the text contains all whitespaces - For blocks: - if it doesn't have any decorations, and doesn't have any children. For performance and to reduce risk of false-negative of layout shift tracking, the conditions are kept simple. If a developer still get unexpected layout shift for invisible elements, we can suggest adding visibility:hidden to the element to explicitly disable layout shift tracking on the element. See https://ct.skia.org/results/cluster-telemetry/tasks/chromium_perf_runs/wangxianzhu-ChromiumPerf-5677/html/index.html for the change of overall CLS score with this CL. Bug: 1099350 Change-Id: Ib7e89e0331663572d1eef511976556e8b2a96a96 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2743811 Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org> Reviewed-by: Steve Kobes <skobes@chromium.org> Reviewed-by: Nicolás Peña Moreno <npm@chromium.org> Cr-Commit-Position: refs/heads/master@{#862593} 
diff --git a/layout-instability/buffer-layout-shift.html b/layout-instability/buffer-layout-shift.html index 705569f..1db0452 100644 --- a/layout-instability/buffer-layout-shift.html +++ b/layout-instability/buffer-layout-shift.html 
@@ -3,7 +3,7 @@  <title>Layout Instability entries are not available via the performance timeline</title>  <body>  <style> -#myDiv { position: relative; width: 300px; height: 100px; } +#myDiv { position: relative; width: 300px; height: 100px; background: blue; }  </style>  <div id='myDiv'></div>  <script src="/resources/testharness.js"></script> 
diff --git a/layout-instability/buffered-flag.html b/layout-instability/buffered-flag.html index 1c67262..a2e9179 100644 --- a/layout-instability/buffered-flag.html +++ b/layout-instability/buffered-flag.html 
@@ -3,7 +3,7 @@  <title>Layout Instability: PerformanceObserver sees entries with buffered flag</title>  <body>  <style> -#myDiv { position: relative; width: 300px; height: 100px; } +#myDiv { position: relative; width: 300px; height: 100px; background: blue; }  </style>  <div id='myDiv'></div>  <script src="/resources/testharness.js"></script> 
diff --git a/layout-instability/child-shift-with-parent-overflow-hidden.html b/layout-instability/child-shift-with-parent-overflow-hidden.html index ba67f7e..f7e9e02 100644 --- a/layout-instability/child-shift-with-parent-overflow-hidden.html +++ b/layout-instability/child-shift-with-parent-overflow-hidden.html 
@@ -6,7 +6,7 @@  <script src="resources/util.js"></script>  <div id="parent" style="position: relative; width: 200px; height: 200px;  border: 50px solid blue; overflow: hidden"> - <div id="child" style="width: 400px; height: 400px"></div> + <div id="child" style="width: 400px; height: 400px; background: blue"></div>  </div>  <script>   
diff --git a/layout-instability/child-shift-with-parent-overflow-x-clip.html b/layout-instability/child-shift-with-parent-overflow-x-clip.html index 381727c..7a85d16 100644 --- a/layout-instability/child-shift-with-parent-overflow-x-clip.html +++ b/layout-instability/child-shift-with-parent-overflow-x-clip.html 
@@ -5,7 +5,7 @@  <script src="/resources/testharnessreport.js"></script>  <script src="resources/util.js"></script>  <div id="parent" style="position: relative; width: 100px; height: 100px; border: 100px solid blue; overflow-x: clip"> - <div id="child" style="width: 1000px; height: 300px"></div> + <div id="child" style="width: 1000px; height: 300px; background: blue"></div>  </div>  <script>   
diff --git a/layout-instability/contain-paint-fully-clipped.html b/layout-instability/contain-paint-fully-clipped.html index bb02b6d..3c0ec72 100644 --- a/layout-instability/contain-paint-fully-clipped.html +++ b/layout-instability/contain-paint-fully-clipped.html 
@@ -2,7 +2,7 @@  <title>Layout Instability: fully clipped by contain:paint</title>  <link rel="help" href="https://wicg.github.io/layout-instability/" />  <div style="contain: paint; height: 0; position: relative"> - <div id="target" style="position: absolute; top: 0; width: 400px; height: 400px"></div> + <div id="target" style="position: absolute; top: 0; width: 400px; height: 400px; background: blue"></div>  </div>  <script src="/resources/testharness.js"></script>  <script src="/resources/testharnessreport.js"></script> 
diff --git a/layout-instability/content-visibility-auto-offscreen.html b/layout-instability/content-visibility-auto-offscreen.html index 6f7af1a..9e4361b 100644 --- a/layout-instability/content-visibility-auto-offscreen.html +++ b/layout-instability/content-visibility-auto-offscreen.html 
@@ -40,8 +40,8 @@  }  </style>  <div class=auto> - <div style="width: 100px; height: 100px"></div> + <div style="width: 100px; height: 100px; background: blue"></div>  </div>  <div id="target" class=auto style="position: relative; top: 100000px"> - <div style="width: 100px; height: 100px"></div> + <div style="width: 100px; height: 100px; background: blue"></div>  </div> \ No newline at end of file 
diff --git a/layout-instability/content-visibility-auto-onscreen.html b/layout-instability/content-visibility-auto-onscreen.html index 6a43080..a7fbd92 100644 --- a/layout-instability/content-visibility-auto-onscreen.html +++ b/layout-instability/content-visibility-auto-onscreen.html 
@@ -23,5 +23,5 @@  }  </style>  <div id=target> - <div style="width: 100px; height: 100px"></div> + <div style="width: 100px; height: 100px; background: blue"></div>  </div> 
diff --git a/layout-instability/content-visibility-auto-resize.html b/layout-instability/content-visibility-auto-resize.html index d692625..bb2d2e5 100644 --- a/layout-instability/content-visibility-auto-resize.html +++ b/layout-instability/content-visibility-auto-resize.html 
@@ -24,6 +24,7 @@  }  .contained {  height: 100px; + background: blue;  }  </style>  <div class=auto><div class=contained></div></div> 
diff --git a/layout-instability/content-visibility-hidden.html b/layout-instability/content-visibility-hidden.html index db087fe..f84cc25 100644 --- a/layout-instability/content-visibility-hidden.html +++ b/layout-instability/content-visibility-hidden.html 
@@ -23,5 +23,5 @@  }  </style>  <div id=target> - <div style="width: 100px; height: 100px"></div> + <div style="width: 100px; height: 100px; background: blue"></div>  </div> 
diff --git a/layout-instability/display-change-with-transform.html b/layout-instability/display-change-with-transform.html index 36aa438..75eb5c5 100644 --- a/layout-instability/display-change-with-transform.html +++ b/layout-instability/display-change-with-transform.html 
@@ -5,6 +5,7 @@  div {  width: 100px;  height: 100px; + background: blue;  }  #target {  transform: translateX(0); 
diff --git a/layout-instability/fully-clipped-visual-rect.html b/layout-instability/fully-clipped-visual-rect.html index bfd74a2..cf308f2 100644 --- a/layout-instability/fully-clipped-visual-rect.html +++ b/layout-instability/fully-clipped-visual-rect.html 
@@ -5,7 +5,7 @@    body { margin: 0; }  #clip { width: 0px; height: 600px; overflow: hidden; } -#j { position: relative; width: 300px; height: 200px; } +#j { position: relative; width: 300px; height: 200px; background: blue; }    </style>  <div id='clip'><div id='j'></div></div> 
diff --git a/layout-instability/ignore-fixed-and-sticky.html b/layout-instability/ignore-fixed-and-sticky.html index 1b39dc9..2023daf 100644 --- a/layout-instability/ignore-fixed-and-sticky.html +++ b/layout-instability/ignore-fixed-and-sticky.html 
@@ -9,6 +9,7 @@  width: 300px;  height: 100px;  left: 100px; + background: yellow;  }  #f1 { top: 0; }  #f2 { top: 150px; will-change: transform; } @@ -18,6 +19,7 @@  height: 100px;  left: 450px;  top: 0; + background: blue;  }    </style> 
diff --git a/layout-instability/input-timestamp.html b/layout-instability/input-timestamp.html index 02dde1a..441387b 100644 --- a/layout-instability/input-timestamp.html +++ b/layout-instability/input-timestamp.html 
@@ -8,6 +8,7 @@  position: relative;  width: 300px;  height: 100px; + background: blue;  }    /* Disable the button's focus ring, which otherwise expands its visual rect by 
diff --git a/layout-instability/local-shift-without-viewport-shift.html b/layout-instability/local-shift-without-viewport-shift.html index 37729f1..d635ed5 100644 --- a/layout-instability/local-shift-without-viewport-shift.html +++ b/layout-instability/local-shift-without-viewport-shift.html 
@@ -4,7 +4,7 @@  <style>    #c { position: relative; width: 300px; height: 100px; transform: scale(0.1); } -#j { position: relative; width: 100px; height: 10px; } +#j { position: relative; width: 100px; height: 10px; background: blue; }    </style>  <div id='c'> 
diff --git a/layout-instability/move-distance-clamped.html b/layout-instability/move-distance-clamped.html index 6c5f959..5854fe0 100644 --- a/layout-instability/move-distance-clamped.html +++ b/layout-instability/move-distance-clamped.html 
@@ -13,6 +13,7 @@  height: 100vh;  left: -2000vw;  top: -2000vh; + background: blue;  }  </style>  <div id="shifter"></div> 
diff --git a/layout-instability/move-transformed.html b/layout-instability/move-transformed.html index c9cdb99..2a7d048 100644 --- a/layout-instability/move-transformed.html +++ b/layout-instability/move-transformed.html 
@@ -3,7 +3,7 @@  <link rel="help" href="https://wicg.github.io/layout-instability/" />  <style>  body { margin: 0; } -#transformed { position: relative; transform: translateX(20px); width: 100px; height: 100px; } +#transformed { position: relative; transform: translateX(20px); width: 100px; height: 100px; background: blue; }  </style>  <div id="transformed"></div>  <script src="/resources/testharness.js"></script> 
diff --git a/layout-instability/multi-clip-visual-rect.html b/layout-instability/multi-clip-visual-rect.html index 36475d4..9237ad8 100644 --- a/layout-instability/multi-clip-visual-rect.html +++ b/layout-instability/multi-clip-visual-rect.html 
@@ -6,7 +6,7 @@  body { margin: 0; }  #outer { width: 200px; height: 600px; overflow: hidden; }  #inner { width: 300px; height: 150px; overflow: hidden; } -#j { position: relative; width: 300px; height: 600px; } +#j { position: relative; width: 300px; height: 600px; background: blue; }    </style>  <div id='outer'><div id='inner'><div id='j'></div></div></div> 
diff --git a/layout-instability/opacity-nonzero-to-zero.html b/layout-instability/opacity-nonzero-to-zero.html index a5f3d21..9ce0f2b 100644 --- a/layout-instability/opacity-nonzero-to-zero.html +++ b/layout-instability/opacity-nonzero-to-zero.html 
@@ -1,7 +1,7 @@  <!DOCTYPE html>  <title>Layout Instability: opacity:0</title>  <link rel="help" href="https://wicg.github.io/layout-instability/" /> -<div id="target" style="position: absolute; top: 0; width: 400px; height: 400px;"> +<div id="target" style="position: absolute; top: 0; width: 400px; height: 400px; background: blue;">  </div>  <script src="/resources/testharness.js"></script>  <script src="/resources/testharnessreport.js"></script> 
diff --git a/layout-instability/opacity-zero-layout-and-visible.html b/layout-instability/opacity-zero-layout-and-visible.html index af81ff2..0172983 100644 --- a/layout-instability/opacity-zero-layout-and-visible.html +++ b/layout-instability/opacity-zero-layout-and-visible.html 
@@ -1,7 +1,7 @@  <!DOCTYPE html>  <title>Layout Instability: opacity:0</title>  <link rel="help" href="https://wicg.github.io/layout-instability/" /> -<div id="target" style="position: absolute; top: 0; width: 200px; height: 200px; opacity: 0"></div> +<div id="target" style="position: absolute; top: 0; width: 200px; height: 200px; opacity: 0; background: blue"></div>  <script src="/resources/testharness.js"></script>  <script src="/resources/testharnessreport.js"></script>  <script src="resources/util.js"></script> 
diff --git a/layout-instability/opacity-zero.html b/layout-instability/opacity-zero.html index e6ce1f0..edd9080 100644 --- a/layout-instability/opacity-zero.html +++ b/layout-instability/opacity-zero.html 
@@ -1,8 +1,8 @@  <!DOCTYPE html>  <title>Layout Instability: opacity:0</title>  <link rel="help" href="https://wicg.github.io/layout-instability/" /> -<div id="target" style="position: absolute; top: 0; width: 400px; height: 400px; opacity: 0"> - <div id="child" style="position: relative; top: 0; width: 200px; height: 200px; opacity: 0.5"></div> +<div id="target" style="position: absolute; top: 0; width: 400px; height: 400px; opacity: 0; background: blue"> + <div id="child" style="position: relative; top: 0; width: 200px; height: 200px; opacity: 0.5; background: yellow"></div>  </div>  <script src="/resources/testharness.js"></script>  <script src="/resources/testharnessreport.js"></script> 
diff --git a/layout-instability/outline.html b/layout-instability/outline.html index 1fed8e9..2b3704f 100644 --- a/layout-instability/outline.html +++ b/layout-instability/outline.html 
@@ -4,7 +4,7 @@  <script src="/resources/testharness.js"></script>  <script src="/resources/testharnessreport.js"></script>  <script src="resources/util.js"></script> -<div id="target" style="width: 300px; height: 300px"></div> +<div id="target" style="width: 300px; height: 300px; background: blue"></div>  <script>  promise_test(async () => {  const watcher = new ScoreWatcher; 
diff --git a/layout-instability/partially-clipped-visual-rect.html b/layout-instability/partially-clipped-visual-rect.html index 3b18b98..d8be37c 100644 --- a/layout-instability/partially-clipped-visual-rect.html +++ b/layout-instability/partially-clipped-visual-rect.html 
@@ -5,7 +5,7 @@    body { margin: 0; }  #clip { width: 150px; height: 600px; overflow: hidden; } -#j { position: relative; width: 300px; height: 200px; } +#j { position: relative; width: 300px; height: 200px; background: blue; }    </style>  <div id='clip'><div id='j'></div></div> 
diff --git a/layout-instability/recent-input.html b/layout-instability/recent-input.html index 292b683..2779d4f 100644 --- a/layout-instability/recent-input.html +++ b/layout-instability/recent-input.html 
@@ -3,7 +3,7 @@  <title>Layout Instability: observe after user input</title>  <body>  <style> -#myDiv { position: relative; width: 300px; height: 100px; } +#myDiv { position: relative; width: 300px; height: 100px; background: blue; }    /* Disable the button's focus ring, which otherwise expands its visual rect by  * 1px on all sides, triggering a layout shift event. 
diff --git a/layout-instability/rtl-distance.html b/layout-instability/rtl-distance.html index a6f0040..6635438 100644 --- a/layout-instability/rtl-distance.html +++ b/layout-instability/rtl-distance.html 
@@ -3,7 +3,7 @@  <link rel="help" href="https://wicg.github.io/layout-instability/" />  <style>   -#shifter { position: relative; width: 100px; height: 100px; direction: rtl; } +#shifter { position: relative; width: 100px; height: 100px; direction: rtl; background: blue; }    </style>  <div id='shifter'></div> 
diff --git a/layout-instability/shift-into-viewport.html b/layout-instability/shift-into-viewport.html index 61267a3..455abd8 100644 --- a/layout-instability/shift-into-viewport.html +++ b/layout-instability/shift-into-viewport.html 
@@ -4,7 +4,7 @@  <style>    body { margin: 0; } -#j { position: absolute; width: 600px; height: 200px; top: 100%; } +#j { position: absolute; width: 600px; height: 200px; top: 100%; background: blue; }    </style>  <div id='j'></div> 
diff --git a/layout-instability/shift-invisible.html b/layout-instability/shift-invisible.html new file mode 100644 index 0000000..3c404a9 --- /dev/null +++ b/layout-instability/shift-invisible.html 
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<title>Layout Instability: shift of invisible element not counted</title> +<link rel="help" href="https://wicg.github.io/layout-instability/" /> +<div id="target" style="width: 100px; height: 100px; position: relative"></div> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/util.js"></script> +<script> + +promise_test(async () => { + const watcher = new ScoreWatcher; + + // Wait for the initial render to complete. + await waitForAnimationFrames(2); + + target.style.top = "200px"; + + await waitForAnimationFrames(3); + assert_equals(watcher.score, 0); +}, "Shift of invisible element not counted."); + +</script> 
diff --git a/layout-instability/shift-outside-viewport.html b/layout-instability/shift-outside-viewport.html index 2d92835..534d56b 100644 --- a/layout-instability/shift-outside-viewport.html +++ b/layout-instability/shift-outside-viewport.html 
@@ -4,7 +4,7 @@  <style>    body { margin: 0; } -#j { position: absolute; width: 600px; height: 200px; top: 100%; } +#j { position: absolute; width: 600px; height: 200px; top: 100%; background: blue; }    </style>  <div id='j'></div> 
diff --git a/layout-instability/shift-while-scrolled.html b/layout-instability/shift-while-scrolled.html index 88eeede..822aa94 100644 --- a/layout-instability/shift-while-scrolled.html +++ b/layout-instability/shift-while-scrolled.html 
@@ -4,7 +4,7 @@  <style>    body { height: 2000px; margin: 0; } -#shift { position: relative; width: 300px; height: 200px; } +#shift { position: relative; width: 300px; height: 200px; background: blue; }    </style>  <div id="shift"></div> 
diff --git a/layout-instability/simple-block-movement.html b/layout-instability/simple-block-movement.html index aafc869..837b438 100644 --- a/layout-instability/simple-block-movement.html +++ b/layout-instability/simple-block-movement.html 
@@ -6,7 +6,7 @@  <script src="resources/test-adapter.js"></script>  <script src="resources/util.js"></script>  <style> -#shifter { position: relative; width: 300px; height: 200px; } +#shifter { position: relative; width: 300px; height: 200px; background: blue; }  </style>  <div id="shifter"></div>  <script> 
diff --git a/layout-instability/sources.html b/layout-instability/sources.html index 599a5c4..5bf3abf 100644 --- a/layout-instability/sources.html +++ b/layout-instability/sources.html 
@@ -4,7 +4,7 @@  <style>    body { margin: 10px; } -#shifter { position: relative; width: 300px; height: 100px; } +#shifter { position: relative; width: 300px; height: 100px; background: blue; }    </style>  <div id="shifter"></div> 
diff --git a/layout-instability/toJSON.html b/layout-instability/toJSON.html index 711cd23..83ee9c9 100644 --- a/layout-instability/toJSON.html +++ b/layout-instability/toJSON.html 
@@ -3,7 +3,7 @@  <title>Layout Instability: toJSON</title>  <body>  <style> -#myDiv { position: relative; width: 300px; height: 100px; } +#myDiv { position: relative; width: 300px; height: 100px; background: blue; }  </style>  <div id='myDiv'></div>  <script src="/resources/testharness.js"></script> 
diff --git a/layout-instability/transform-change.html b/layout-instability/transform-change.html index 3fa2496..ea1f10a 100644 --- a/layout-instability/transform-change.html +++ b/layout-instability/transform-change.html 
@@ -3,7 +3,7 @@  <link rel="help" href="https://wicg.github.io/layout-instability/" />  <style>  body { margin: 0; } -#transformed { position: relative; transform: translateX(20px); width: 100px; height: 100px; } +#transformed { position: relative; transform: translateX(20px); width: 100px; height: 100px; background: blue; }  #child { width: 400px; height: 400px; }  </style>  <div id="transformed"> 
diff --git a/layout-instability/transform-counter-layout-shift.html b/layout-instability/transform-counter-layout-shift.html index fd744e3..476e25a 100644 --- a/layout-instability/transform-counter-layout-shift.html +++ b/layout-instability/transform-counter-layout-shift.html 
@@ -3,7 +3,7 @@  <link rel="help" href="https://wicg.github.io/layout-instability/" />  <style>  body { margin: 0; } -#transformed { position: relative; transform: translateX(20px); width: 100px; height: 100px; } +#transformed { position: relative; transform: translateX(20px); width: 100px; height: 100px; background: blue; }  #child { width: 400px; height: 400px; }  </style>  <div id="transformed"> 
diff --git a/layout-instability/transform.html b/layout-instability/transform.html index 7ac1c8c..98f94f5 100644 --- a/layout-instability/transform.html +++ b/layout-instability/transform.html 
@@ -5,7 +5,7 @@    body { margin: 0; }  #container { transform: translateX(-300px) translateY(-40px); } -#shifter { position: relative; width: 600px; height: 140px; } +#shifter { position: relative; width: 600px; height: 140px; background: blue; }    </style>  <div id="container"> 
diff --git a/layout-instability/visibility-hidden-layout-and-visible.html b/layout-instability/visibility-hidden-layout-and-visible.html index 3fea6bb..35ee0d9 100644 --- a/layout-instability/visibility-hidden-layout-and-visible.html +++ b/layout-instability/visibility-hidden-layout-and-visible.html 
@@ -1,7 +1,7 @@  <!DOCTYPE html>  <title>Layout Instability: visibility:hidden change with layout</title>  <link rel="help" href="https://wicg.github.io/layout-instability/" /> -<div id="target" style="position: absolute; top: 0; width: 200px; height: 200px; visibility: hidden"></div> +<div id="target" style="position: absolute; top: 0; width: 200px; height: 200px; visibility: hidden; background: blue"></div>  <script src="/resources/testharness.js"></script>  <script src="/resources/testharnessreport.js"></script>  <script src="resources/util.js"></script> 
diff --git a/layout-instability/visibility-hidden.html b/layout-instability/visibility-hidden.html index ec1c331..583be10 100644 --- a/layout-instability/visibility-hidden.html +++ b/layout-instability/visibility-hidden.html 
@@ -1,7 +1,7 @@  <!DOCTYPE html>  <title>Layout Instability: visibility:hidden</title>  <link rel="help" href="https://wicg.github.io/layout-instability/" /> -<div id="target" style="position: absolute; top: 0; width: 400px; height: 400px; visibility: hidden"></div> +<div id="target" style="position: absolute; top: 0; width: 400px; height: 400px; visibility: hidden; background: blue"></div>  <script src="/resources/testharness.js"></script>  <script src="/resources/testharnessreport.js"></script>  <script src="resources/util.js"></script> 
diff --git a/layout-instability/visible-to-hidden.html b/layout-instability/visible-to-hidden.html index e30231f..d6ac75a 100644 --- a/layout-instability/visible-to-hidden.html +++ b/layout-instability/visible-to-hidden.html 
@@ -1,7 +1,7 @@  <!DOCTYPE html>  <title>Layout Instability: visibility:hidden</title>  <link rel="help" href="https://wicg.github.io/layout-instability/" /> -<div id="target" style="position: absolute; top: 0; width: 400px; height: 400px;"></div> +<div id="target" style="position: absolute; top: 0; width: 400px; height: 400px; background: blue;"></div>  <script src="/resources/testharness.js"></script>  <script src="/resources/testharnessreport.js"></script>  <script src="resources/util.js"></script>